﻿using System;
using System.Collections.Generic;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Text.RegularExpressions;

namespace proLearningEnglish
{
    public partial class frmNewWord : Form
    {
        //private DataManager objDataManager;
        private TreeNode wordNodeSelected = null;
        private TreeNode senseNodeSelected = null;
        
        public frmNewWord()
        {
            InitializeComponent();  
        }

        private void frmNewWord_Load(object sender, EventArgs e)
        {
            loadWordSense();
            loadWord();
            TreeNode topNode = treNewWordDetail.Nodes.Add("Danh sách từ mới:");
            treNewWordDetail.TopNode = topNode;
        }

        private void loadWordSense()
        {
            cmbWordSense.Nodes.Clear();
            ComboTreeNode rootNode = new ComboTreeNode("Nghĩa tiếng Việt");
            cmbWordSense.Nodes.Add(rootNode);
            List<WordSense> lst = frmMain.objDataManager.getIsARootWordSenseNodes();
            for (int i = 0; i < lst.Count; i++)
            {
                addNode(rootNode, lst[i]);
            }
            cmbWordSense.ExpandAll();
        }

        private void loadWord()
        {
            cmbWord.Nodes.Clear();
            /*ComboTreeNode rootNode = new ComboTreeNode("Từ tiếng Anh");
            cmbWord.Nodes.Add(rootNode);
            List<Word> lst = objDataManager.getIsARootWordNodes();
            for (int i = 0; i < lst.Count; i++)
            {
                addNode(rootNode, lst[i]);
            }
            cmbWord.ExpandAll();
             * */
            List<Word> lstWord = frmMain.objDataManager.getWordList();
            foreach (Word objWord in lstWord)
            {
                List<WordSense> lstSense = frmMain.objDataManager.getAllWordSenseOfWord(objWord);
                foreach (WordSense s in lstSense)
                {
                    SimpleWord w = new SimpleWord(objWord.getLabel(), s);
                    ComboTreeNode nodeTmp = this.cmbWord.Nodes.Add(w.getLabel() + " : " + w.getSense().getLabel());
                    nodeTmp.Tag = w; 
                }
            }
        }

        private void addNode(ComboTreeNode node, WordSense objWordSense)
        {
            ComboTreeNode nodeTmp = node.Nodes.Add(objWordSense.getID(), objWordSense.getLabel() + " (" +  objWordSense.getTypeString() + ")");
            nodeTmp.Tag = objWordSense;
            List<WordSense> lst = frmMain.objDataManager.getIsAChildWordSenseNodes(objWordSense);
            for (int i = 0; i < lst.Count; i++)
            {
                addNode(nodeTmp, lst[i]);
            }
        }

        private void btnTest_Click(object sender, EventArgs e)
        {
            if (txtNewWord.Text == "")
            {
                MessageBox.Show("Từ không thể rỗng !");
                return;
            }            
            Word word = new Word(txtNewWord.Text);
            if(this.treNewWordDetail.Nodes.ContainsKey(word.getID()))
            {
                MessageBox.Show("Từ đã tồn tại !");
                return;
            }            
            TreeNode nodeWord = treNewWordDetail.TopNode.Nodes.Add(word.getID(), word.getLabel());
            nodeWord.ForeColor = Color.Red;
            nodeWord.Tag = word;
            if(this.wordNodeSelected != null) this.wordNodeSelected.BackColor = Color.White;
            this.wordNodeSelected = nodeWord;
            this.wordNodeSelected.BackColor = Color.Yellow;
            treNewWordDetail.ExpandAll();
            this.btnDeleteNewWord.Enabled = true;
        }

        private void btnAddSenseForWord_Click(object sender, EventArgs e)
        {
            if (cmbWordSense.SelectedNode == null || cmbWordSense.SelectedNode == cmbWordSense.TopNode)
            {
                MessageBox.Show("Chọn một nghĩa cho từ !");
                return;
            }
            else
            {
                WordSense sense = (WordSense)cmbWordSense.SelectedNode.Tag;
                if (treNewWordDetail.TopNode.Nodes.Count == 0)
                {
                    MessageBox.Show("Bạn chưa nhập từ mới !");
                    return;
                }

                else if (wordNodeSelected.Nodes.Count == 0)
                {
                }
                else if (findSenseInWord(sense.getID()))
                {
                    MessageBox.Show("Từ đã có nghĩa này !");
                    return;
                }

                TreeNode nodeType = wordNodeSelected.Nodes.ContainsKey(sense.getTypeString()) ? 
                    wordNodeSelected.Nodes.Find(sense.getTypeString(), false)[0] :
                    wordNodeSelected.Nodes.Add(sense.getTypeString(), sense.getTypeString());

                TreeNode nodeSense = nodeType.Nodes.Add(sense.getID(), sense.getLabel());
                this.senseNodeSelected = nodeSense;
                this.senseNodeSelected.BackColor = Color.Yellow;
                if (this.cmbWord.SelectedNode != null)
                    this.btnAddIsA.Enabled = this.btnAddAntonym.Enabled = this.btnAddSynonym.Enabled = true;
                nodeSense.Tag = sense;
                nodeSense.ForeColor = Color.Blue;        

                //view relation: is a
                Word wordIsA = frmMain.objDataManager.getWordIsAWord(sense);
                if (wordIsA != null)
                {
                    TreeNode nodeIsA = nodeSense.Nodes.Add("isa", "Is a:");
                    TreeNode isa = nodeIsA.Nodes.Add(wordIsA.getID(), wordIsA.getLabel());
                    isa.ForeColor = Color.Blue;
                }
                
                //view relation: synonym
                List<Word> lstSyn = frmMain.objDataManager.getWordSynonym(sense);
                if (lstSyn.Count > 0)
                {
                    TreeNode nodeSyn = nodeSense.Nodes.Add("synonym", "Synonym:");
                    foreach (Word w in lstSyn)
                    {
                        TreeNode syn = nodeSyn.Nodes.Add(w.getID(), w.getLabel());
                        syn.ForeColor = Color.Blue;
                    }
                }
                //view relation: antonym
                List<Word> lstAnto = frmMain.objDataManager.getWordAntonym(sense);
                if (lstAnto.Count > 0)
                {
                    TreeNode nodeAnto = nodeSense.Nodes.Add("antonym", "Antonym:");
                    foreach (Word w in lstAnto)
                    {
                        TreeNode anto = nodeAnto.Nodes.Add(w.getID(), w.getLabel());
                        anto.ForeColor = Color.Blue;
                    }
                }
                this.treNewWordDetail.ExpandAll();
                this.txtNewWord.Text = null;
            }
        }

        private void treNewWordDetail_AfterSelect(object sender, TreeViewEventArgs e)
        {
            if (e.Node != null)
            {
                if (e.Node == treNewWordDetail.TopNode)
                {
                    this.btnDeleteNewWord.Enabled = false;
                    return;
                }
                this.findWordNodeSelected(e.Node);
                this.findSenseSelected(e.Node);
                this.btnDeleteNewWord.Enabled = true;
                this.btnAddAntonym.Enabled = this.btnAddIsA.Enabled = this.btnAddSynonym.Enabled = (this.senseNodeSelected == null) ? false : true;
            }
        }

        private void findWordNodeSelected(TreeNode node)
        {
            if (node.Parent == treNewWordDetail.TopNode)
            {
                if(this.wordNodeSelected != null) this.wordNodeSelected.BackColor = Color.White;
                this.wordNodeSelected = node;
                this.wordNodeSelected.BackColor = Color.Yellow;
                return;
            }
            else findWordNodeSelected(node.Parent);
        }

        private void findSenseSelected(TreeNode node)
        {
            if (WordSense.WORDTYPELIST.Contains<string>(node.Parent.Text))
            {
                if(this.senseNodeSelected != null) this.senseNodeSelected.BackColor = Color.White;
                this.senseNodeSelected = node;
                this.senseNodeSelected.BackColor = Color.Yellow;
                if(this.cmbWord.SelectedNode != null)
                    this.btnAddAntonym.Enabled = this.btnAddSynonym.Enabled = this.btnAddIsA.Enabled = true;
                return;
            }
            else if (node.Parent == this.treNewWordDetail.TopNode)
            {
                if (this.senseNodeSelected != null) this.senseNodeSelected.BackColor = Color.White;
                this.senseNodeSelected = null;
                this.btnAddAntonym.Enabled = this.btnAddSynonym.Enabled = this.btnAddIsA.Enabled = false;
                return;
            }
            else findSenseSelected(node.Parent);
        }

        private bool findSenseInWord(String strKey)
        {
            if (wordNodeSelected.Nodes.Find(strKey, true).Length > 0)
                return true;
            return false;
        }

        private void btnAddNewSense_Click(object sender, EventArgs e)
        {
            frmNewSense frm = new frmNewSense();
            frm.Show();
            //frmNewWordSense frm2 = new frmNewWordSense();
            //frm2.Show();
        }

        private void txtNewWord_Leave(object sender, EventArgs e)
        {
            string str = this.txtNewWord.Text.Trim();
            str = Regex.Replace(str, " +", " ");
            this.txtNewWord.Text = str;
        }

        private void btnAddAntonym_Click(object sender, EventArgs e)
        {
            /*frmAddRelation frm = new frmAddRelation(this.objDataManager, ((WordSense)this.senseNodeSelected.Tag).getTypeString());
            frm.Text = "Từ trái nghĩa";
            frm.ShowDialog(this);*/

            SimpleWord sw = (SimpleWord)cmbWord.SelectedNode.Tag;
            if (senseNodeSelected.Nodes.ContainsKey("antonym"))
            {
                TreeNode antoNode = this.senseNodeSelected.Nodes.Find("antonym", false)[0];
                if (antoNode.Nodes.ContainsKey(sw.getID()))
                    return;
                else
                {
                    TreeNode n = antoNode.Nodes.Add(sw.getID(), sw.getLabel());
                    n.Tag = sw;
                    n.ForeColor = Color.Blue;
                    senseNodeSelected.ExpandAll();
                }
            }
            else
            {
                TreeNode antoNode = senseNodeSelected.Nodes.Add("antonym", "Antonym:");
                TreeNode n = antoNode.Nodes.Add(sw.getID(), sw.getLabel());
                n.Tag = sw;
                n.ForeColor = Color.Blue;
                senseNodeSelected.ExpandAll();
            }
        }

        private void btnAddIsA_Click(object sender, EventArgs e)
        {
            SimpleWord sw = (SimpleWord)cmbWord.SelectedNode.Tag;
            if (senseNodeSelected.Nodes.ContainsKey("isa"))
            {
                TreeNode isaNode = senseNodeSelected.Nodes.Find("isa", false)[0];                
                if (isaNode.Nodes.ContainsKey(sw.getID()))
                    return;
                else
                {
                    isaNode.Nodes.Clear();
                    TreeNode n = isaNode.Nodes.Add(sw.getID(), sw.getLabel());
                    n.Tag = sw;
                    n.ForeColor = Color.Blue;
                    senseNodeSelected.ExpandAll();
                }
            }
            else
            {
                TreeNode nodeIsA = senseNodeSelected.Nodes.Add("isa", "Is a: ");
                TreeNode n = nodeIsA.Nodes.Add(sw.getID(), sw.getLabel());
                n.Tag = sw;
                n.ForeColor = Color.Blue;
                senseNodeSelected.ExpandAll();
            }
        }

        private void btnAddSynonym_Click(object sender, EventArgs e)
        {
            SimpleWord sw = (SimpleWord)cmbWord.SelectedNode.Tag;
            if (this.senseNodeSelected.Nodes.ContainsKey("synonym"))
            {
                TreeNode synNode = senseNodeSelected.Nodes.Find("synonym", false)[0];
                if (synNode.Nodes.ContainsKey(sw.getID()))
                    return;
                else
                {
                    TreeNode n = synNode.Nodes.Add(sw.getID(), sw.getLabel());
                    n.Tag = sw;
                    n.ForeColor = Color.Blue;
                    this.senseNodeSelected.ExpandAll();
                }
            }
            else
            {
                TreeNode synNode = senseNodeSelected.Nodes.Add("synonym", "Synonym:");
                TreeNode n = synNode.Nodes.Add(sw.getID(), sw.getLabel());
                n.Tag = sw;
                n.ForeColor = Color.Blue;
                this.senseNodeSelected.ExpandAll();
            }
        }

        private void btnRefresh_Click(object sender, EventArgs e)
        {
            this.txtNewWord.Text = null;
            this.treNewWordDetail.TopNode.Nodes.Clear();
            this.cmbWord.SelectedNode = null;
            this.cmbWordSense.SelectedNode = null;
            this.btnAddIsA.Enabled = this.btnAddSynonym.Enabled = this.btnAddAntonym.Enabled = false;
        }

        private void cmbWord_SelectedNodeChanged(object sender, EventArgs e)
        {
            this.btnAddIsA.Enabled = this.btnAddSynonym.Enabled = this.btnAddAntonym.Enabled = (senseNodeSelected != null && cmbWord.SelectedNode != null) ? true : false;
        }

        private void cmbWordSense_SelectedNodeChanged(object sender, EventArgs e)
        {
            this.btnAddSenseForWord.Enabled = (this.wordNodeSelected != null && this.cmbWordSense.SelectedNode != null && this.cmbWordSense.SelectedNode != cmbWordSense.TopNode) ? true : false;
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            foreach (TreeNode nodeWord in treNewWordDetail.TopNode.Nodes)
            {
                Word w = new Word(nodeWord.Text);
                frmMain.objDataManager.addWord(w);
                string type = null;
                foreach ( TreeNode nodeType in nodeWord.Nodes )
                {
                    type = nodeType.Text;
                    foreach (TreeNode nodeSense in nodeType.Nodes)
                    {
                        WordSense sense = (WordSense)nodeSense.Tag;
                        frmMain.objDataManager.addRelation(w, frmMain.objDataManager.HasSense, sense);
                        if ( nodeSense.Nodes.ContainsKey ( "isa" ))
                        {
                            TreeNode nodeIsA = nodeSense.Nodes.Find("isa", false)[0].Nodes[0];
                            SimpleWord sw = (SimpleWord)nodeIsA.Tag;
                            frmMain.objDataManager.removeRelation(sense, frmMain.objDataManager.IsA);
                            frmMain.objDataManager.addRelation(sense, frmMain.objDataManager.IsA, sw.getSense());
                        }
                        if ( nodeSense.Nodes.ContainsKey ( "synonym" ))
                        {
                            TreeNode nodeSyn = nodeSense.Nodes.Find("synonym", false)[0];
                            foreach (TreeNode node in nodeSyn.Nodes)
                            {
                                SimpleWord sw = (SimpleWord)node.Tag;
                                frmMain.objDataManager.addRelation(sense, frmMain.objDataManager.SynonymWith, sw.getSense());
                            }
                        }
                        if (nodeSense.Nodes.ContainsKey("antonym"))
                        {
                            TreeNode nodeAnto = nodeSense.Nodes.Find("antonym", false)[0];
                            foreach (TreeNode node in nodeAnto.Nodes)
                            {
                                SimpleWord sw = (SimpleWord)node.Tag;
                                frmMain.objDataManager.addRelation(sense, frmMain.objDataManager.AntonymWith, sw.getSense());
                            }
                        }
                        //objDataManager.addWordSense(sense);
                    }
                }                
            }
            //frmMain.objDataManager.save();
            //MessageBox.Show("Lưu dữ liệu thành công!");
            this.Dispose();
        }

        private void btnExit_Click(object sender, EventArgs e)
        {
            this.Dispose();
        }

    }
}
